using System;
using System.Collections.Generic;
using System.IO;
using CodePlex.TfsLibrary;
using CodePlex.TfsLibrary.ClientEngine;
using CodePlex.TfsLibrary.ObjectModel;

namespace CodePlex.CodePlexClientLibrary
{
    public class DiffConsoleView
    {
        readonly ITfsEngine engine;

        public DiffConsoleView(ITfsEngine engine)
        {
            this.engine = engine;
        }

        static void DiffCallback(string basePath,
                                 string leftPathname,
                                 string leftVersion,
                                 string rightPathname,
                                 string rightVersion,
                                 List<DiffEngine.Chunk> diff,
                                 SourceItemResult result)
        {
            if (result != SourceItemResult.S_Ok)
                ConsoleUtil.PrintCommandError(leftPathname, result);
            else
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("--- {0}    ({1})", CodePlexClientUtil.GetRelativePath(basePath, leftPathname), leftVersion);
                Console.WriteLine("+++ {0}    ({1})", CodePlexClientUtil.GetRelativePath(basePath, rightPathname), rightVersion);

                UniversalDiff.Diff(diff, PrintLine);
            }
        }

        static char OperationChar(DiffEngine.ChunkType type)
        {
            switch (type)
            {
                case DiffEngine.ChunkType.Right:
                    return '+';
                case DiffEngine.ChunkType.Left:
                    return '-';
                default:
                    return ' ';
            }
        }

        static void PrintLine(UniversalDiff.Block block)
        {
            Console.WriteLine("@@ -{0},{1} +{2},{3} @@", block.LeftStartLine, block.LeftContentLength, block.RightStartLine, block.RightContentLength);

            foreach (DiffEngine.Chunk chunk in block.Chunks)
                foreach (string line in chunk.Lines)
                    Console.WriteLine("{0}{1}", OperationChar(chunk.ChunkType), line);
        }

        public void Run(string basePath,
                        bool recursive,
                        string path)
        {
            engine.Diff(CodePlexClientUtil.GetFullPath(path), recursive,
                        delegate(string leftPathname,
                                 string leftVersion,
                                 string rightPathname,
                                 string rightVersion,
                                 List<DiffEngine.Chunk> diff,
                                 SourceItemResult result)
                        {
                            DiffCallback(Directory.GetCurrentDirectory(), leftPathname, leftVersion, rightPathname, rightVersion, diff, result);
                        });
        }
    }
}